Supplementary text S1
Local correlates of municipality-level excess mortality in Switzerland in 2020
Data
Age group | Sex | Observed | Expected (median) | Expected (lower bound) | Expected (upper bound) | Ratio (median) | Ratio (lower bound) | Ratio (upper bound) |
|---|---|---|---|---|---|---|---|---|
40-59 | Female | 1,713 | 1,769 | 1,642 | 1,895 | 0.97 | 0.90 | 1.04 |
40-59 | Male | 2,966 | 2,230 | 2,074 | 2,396 | 1.33 | 1.24 | 1.43 |
60-69 | Female | 2,611 | 2,592 | 2,421 | 2,753 | 1.01 | 0.95 | 1.08 |
60-69 | Male | 4,478 | 3,201 | 3,013 | 3,449 | 1.40 | 1.30 | 1.49 |
70-79 | Female | 6,203 | 5,028 | 4,708 | 5,376 | 1.23 | 1.15 | 1.32 |
70-79 | Male | 8,972 | 5,953 | 5,615 | 6,310 | 1.51 | 1.42 | 1.60 |
80+ | Female | 27,541 | 17,205 | 16,453 | 18,284 | 1.60 | 1.51 | 1.67 |
80+ | Male | 20,292 | 17,677 | 16,791 | 18,900 | 1.15 | 1.07 | 1.21 |
Total | Total | 74,776 | 55,676 | 53,865 | 57,821 | 1.34 | 1.29 | 1.39 |
Models of observed and expected deaths by municipality
Step 1: iterative model development
To facilitate model development we only use the median excess mortality by municipality, age group and sex in 2020.
data1 = exp_deaths_2020_year %>%
group_by(canton, GMDNR, GMDNAME, age_group, id_space, sex, munici_observed, munici_pop,
density_high, density_low, across(starts_with("sep")), border, lang_fr, lang_it,
across(starts_with("vote")),type_urban,type_rural,type_periurban) %>%
summarise(munici_exp_deaths=median(munici_exp_deaths),
munici_excess=median(munici_excess)) %>%
mutate(E=log(ifelse(munici_exp_deaths==0,1e-4,munici_exp_deaths))) %>%
ungroup()
rm(exp_deaths_2020_year)
# gc()hyper.iid = list(theta = list(prior = "pc.prec", param = c(1, 0.01)))
hyper.bym2 = list(theta1 = list("PCprior", c(1, 0.01)),
theta2 = list("PCprior", c(0.5, 0.5)))
threads = parallel::detectCores()Model 1.0: no covariates
We use a model structure similar to Poisson regression, where \(O_{t,i,j,k}\), the number of observed deaths during week \(t\) in municipality \(i\), age group \(j\) and sex group \(k\), depends on the number of expected deaths \(E_{t,i,j,k}\) based on historical data and a linear predictor \(\lambda\).
\[ O_i \sim \text{Poisson}(E_i \times \exp(\lambda)) \\ \] At start, the linear predictor \(\lambda\) only includes one intercept parameter \(\alpha\), so that the estimate of \(\exp(\alpha)\) can be interpreted as an average relative excess mortality for 2020. By adding covariates to \(\lambda\), we aim to disentangle the various factors that are associated with excess mortality at the local level.
We implement this model in R-INLA, a Bayesian inference package that is especially adapted to spatial data. This is achieved in practice by including \(\log (E_{i,j,k})\) as an offset (although an alternative formulation based on the E argument exists). During model development, we compare different model versions based on the WAIC (lower values imply a better fit).
model1.0 = INLA::inla(munici_observed ~ 1 + offset(E),
data = data1,
family = "Poisson",
control.compute = list(config = TRUE, waic = TRUE),
quantiles = c(0.025, 0.5, 0.975),
num.threads = threads,
safe = TRUE)
summary(model1.0)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 0.557, Running = 0.42, Post = 0.0724, Total = 1.05
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
(Intercept) 0.325 0.004 0.317 0.325 0.332 0.325 0
Watanabe-Akaike information criterion (WAIC) ...: 49278.96
Effective number of parameters .................: 3.53
Marginal log-Likelihood: -24648.51
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mean 0.025quant 0.975quant
(Intercept) 1.383534 1.373679 1.39346
[1] 1.383562
As a sanity check, we find a relative excess mortality of 38% for 2020, that is coherent with a simple calculation (74,776 observed / 54,046 expected = 1.38). Remember that we excluded the age group 0-40, which explains why this is higher than numbers reported for Switzerland, generally around 10% for 2020. We can also look at the model fit and at the residuals. Obviously the model fit is not good here, as this basic model assumes a unique relative excess mortality for all areas, sexes and age groups.
Model 1.1: age and sex
We hypothesize that excess mortality affected different age and sex groups differently. We thus add the age group, the sex and the interaction of the two as covariates.
model1.1 = INLA::inla(munici_observed ~ - 1 + offset(E) +
sex:age_group,
data = data1,
family = "Poisson",
control.compute = list(config = TRUE, waic = TRUE),
quantiles = c(0.025, 0.5, 0.975),
num.threads = threads,
safe = TRUE)
summary(model1.1)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 0.406, Running = 0.623, Post = 0.0817, Total = 1.11
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
sexFemale:age_group40-59 0.008 0.024 -0.040 0.008 0.055 0.008 0
sexMale:age_group40-59 0.354 0.018 0.318 0.354 0.390 0.354 0
sexFemale:age_group60-69 0.035 0.020 -0.003 0.035 0.074 0.035 0
sexMale:age_group60-69 0.417 0.015 0.388 0.417 0.447 0.417 0
sexFemale:age_group70-79 0.235 0.013 0.210 0.235 0.260 0.235 0
sexMale:age_group70-79 0.473 0.011 0.453 0.473 0.494 0.473 0
sexFemale:age_group80+ 0.493 0.006 0.481 0.493 0.504 0.493 0
sexMale:age_group80+ 0.149 0.007 0.136 0.149 0.163 0.149 0
Watanabe-Akaike information criterion (WAIC) ...: 47190.67
Effective number of parameters .................: 4.17
Marginal log-Likelihood: -23651.68
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mean 0.025quant 0.975quant
sexFemale:age_group40-59 1.007864 0.9612512 1.056738
sexMale:age_group40-59 1.424950 1.3745805 1.477166
sexFemale:age_group60-69 1.036069 0.9970809 1.076581
sexMale:age_group60-69 1.517741 1.4739324 1.562852
sexFemale:age_group70-79 1.264505 1.2334258 1.296368
sexMale:age_group70-79 1.605326 1.5724496 1.638889
sexFemale:age_group80+ 1.636631 1.6174162 1.656075
sexMale:age_group80+ 1.161138 1.1452712 1.177224
[1] -2088.29
As expected, the relative excess mortality varies a lot across age and sex groups. It’s very small in females aged 40-59 and 60-69 (in fact the data is compatible with no excess in both cases). It increases in females aged 70-79, and even more so aged 80+. It’s comparatively higher in males below 80, but somewhat surprisingly lower in males in age group 80+. We observe an improvement of the model fit, not easy to spot on the plot because of the large number of points, but made clear by the large decrease in WAIC.
Model 1.2: spatial variability
We now account for spatial variability, first in a simple way using an i.i.d. random effect, so that all municipalities can vary independently from each other around a global average.
model1.2 = INLA::inla(munici_observed ~ - 1 + offset(E) +
sex:age_group +
f(id_space, model = "iid"),
data = data1,
family = "Poisson",
control.compute = list(config = TRUE, waic = TRUE),
quantiles = c(0.025, 0.5, 0.975),
num.threads = threads,
safe = TRUE)
summary(model1.2)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 0.447, Running = 1.45, Post = 0.172, Total = 2.07
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
sexFemale:age_group40-59 0.011 0.024 -0.036 0.011 0.058 0.011 0
sexMale:age_group40-59 0.358 0.018 0.322 0.358 0.394 0.358 0
sexFemale:age_group60-69 0.039 0.020 0.001 0.039 0.078 0.039 0
sexMale:age_group60-69 0.420 0.015 0.391 0.420 0.450 0.420 0
sexFemale:age_group70-79 0.238 0.013 0.213 0.238 0.263 0.238 0
sexMale:age_group70-79 0.477 0.011 0.456 0.477 0.498 0.477 0
sexFemale:age_group80+ 0.497 0.006 0.485 0.497 0.509 0.497 0
sexMale:age_group80+ 0.153 0.007 0.139 0.153 0.167 0.153 0
Random effects:
Name Model
id_space IID model
Model hyperparameters:
mean sd 0.025quant 0.5quant 0.975quant mode
Precision for id_space 3453.45 2510.49 1339.89 2741.78 9707.17 2116.51
Watanabe-Akaike information criterion (WAIC) ...: 47159.19
Effective number of parameters .................: 14.49
Marginal log-Likelihood: -23646.50
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mean 0.025quant 0.975quant
sexFemale:age_group40-59 1.011058 0.9641761 1.060222
sexMale:age_group40-59 1.430421 1.3796297 1.483087
sexFemale:age_group60-69 1.039892 1.0006107 1.080718
sexMale:age_group60-69 1.522570 1.4783840 1.568084
sexFemale:age_group70-79 1.268978 1.2375430 1.301220
sexMale:age_group70-79 1.610709 1.5773914 1.644743
sexFemale:age_group80+ 1.643565 1.6234816 1.663948
sexMale:age_group80+ 1.165188 1.1488960 1.181732
[1] -31.47579
The age and sex effect remains similar, but the model fit as measured by the WAIC is improved now that we account for local differences. We can observe this municipality effect, that applies in all age and sex groups of the municipality in exactly the same way.
We find noisy estimates in some places, suggesting issues related to small area estimation. One solution is to partially pool information between municipalities that are geographically linked.
Model 1.3: structured spatial variability
We still focus on spatial variability, but now the municipalities are no longer independent: we account for the correlation between neighboring municipalities with a BYM model. This will allow us to differentiate between what can be attributed to a municipality in particular, and what can be attributed to regional effects (like a COVID wave).
model1.3 = INLA::inla(munici_observed ~ - 1 + offset(E) +
sex:age_group +
f(id_space, model = "bym2", graph = "data/nb/gg_wm_q.adj", scale.model = TRUE,
hyper = hyper.bym2, constr=TRUE),
data = data1,
family = "Poisson",
control.compute = list(config = TRUE, waic = TRUE),
quantiles = c(0.025, 0.5, 0.975),
num.threads = threads,
safe = TRUE)
summary(model1.3)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 14.1, Running = 5.49, Post = 0.386, Total = 20
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
sexFemale:age_group40-59 0.015 0.024 -0.032 0.015 0.063 0.015 0
sexMale:age_group40-59 0.362 0.018 0.326 0.362 0.398 0.362 0
sexFemale:age_group60-69 0.044 0.020 0.005 0.044 0.083 0.044 0
sexMale:age_group60-69 0.427 0.015 0.398 0.427 0.457 0.427 0
sexFemale:age_group70-79 0.243 0.013 0.218 0.243 0.269 0.243 0
sexMale:age_group70-79 0.482 0.011 0.461 0.482 0.503 0.482 0
sexFemale:age_group80+ 0.502 0.006 0.489 0.502 0.514 0.502 0
sexMale:age_group80+ 0.158 0.007 0.144 0.158 0.172 0.158 0
Random effects:
Name Model
id_space BYM2 model
Model hyperparameters:
mean sd 0.025quant 0.5quant 0.975quant mode
Precision for id_space 708.294 153.582 454.508 691.927 1056.622 660.072
Phi for id_space 0.976 0.033 0.885 0.987 0.999 0.997
Watanabe-Akaike information criterion (WAIC) ...: 46981.08
Effective number of parameters .................: 13.87
Marginal log-Likelihood: -22734.63
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mean 0.025quant 0.975quant
sexFemale:age_group40-59 1.015557 0.9683697 1.065045
sexMale:age_group40-59 1.436467 1.3853112 1.489516
sexFemale:age_group60-69 1.045073 1.0055075 1.086197
sexMale:age_group60-69 1.533097 1.4884052 1.579135
sexFemale:age_group70-79 1.275496 1.2437259 1.308085
sexMale:age_group70-79 1.619883 1.5860644 1.654433
sexFemale:age_group80+ 1.651270 1.6306364 1.672205
sexMale:age_group80+ 1.171048 1.1543623 1.187992
[1] -178.1102
We see that the structure accounts for about half of the spatial variability (Phi estimated to 0.5). This addition also improves the model fit as measured by the WAIC.
We observe that many of the municipalities with higher relative excess mortality are in the western and southern parts, the ones that were hit first by COVID-19 in 2020. We also observe areas with higher excess in the North and Northeastern parts. These largely correspond to areas that were hit the most during the first and the second COVID-19 waves of spring and fall 2020 (REF Konstantinoudis et al NatCom 2022).
Model 1.4: local characteristics
Having accounted for regional variability (arguably caused by COVID-19 waves of different timings and scales), we move on to explore the effect of local characteristics at the municipality level.
Rural/urban
The Federal Statistical Office classifies Swiss municipalities in 3 classes: urban, rural or intermediate (https://www.bfs.admin.ch/bfs/en/home/statistics/territory-environment/nomenclatures/gemtyp.html). We add this covariate to the model taking the “intermediate” category as the reference, and including an interaction with age.
model1.4a = INLA::inla(munici_observed ~ - 1 + offset(E) +
sex:age_group +
f(id_space, model = "bym2", graph = "data/nb/gg_wm_q.adj", scale.model = TRUE,
hyper = hyper.bym2, constr=TRUE) +
age_group:type_periurban + age_group:type_urban,
data = data1,
family = "Poisson",
control.compute = list(config = TRUE, waic = TRUE),
quantiles = c(0.025, 0.5, 0.975),
num.threads = threads,
safe = TRUE)
summary(model1.4a)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 11.9, Running = 4.81, Post = 0.72, Total = 17.4
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
sexFemale:age_group40-59 0.032 0.041 -0.049 0.032 0.114 0.032 0
sexMale:age_group40-59 0.380 0.038 0.304 0.380 0.455 0.380 0
sexFemale:age_group60-69 0.099 0.033 0.034 0.099 0.164 0.099 0
sexMale:age_group60-69 0.482 0.030 0.422 0.482 0.541 0.482 0
sexFemale:age_group70-79 0.312 0.022 0.268 0.312 0.356 0.312 0
sexMale:age_group70-79 0.551 0.022 0.509 0.551 0.593 0.551 0
sexFemale:age_group80+ 0.534 0.013 0.509 0.534 0.558 0.533 0
sexMale:age_group80+ 0.189 0.013 0.164 0.189 0.215 0.189 0
age_group40-59:type_periurban 0.010 0.049 -0.085 0.010 0.105 0.010 0
age_group60-69:type_periurban -0.037 0.039 -0.113 -0.037 0.039 -0.037 0
age_group70-79:type_periurban -0.051 0.027 -0.104 -0.051 0.002 -0.051 0
age_group80+:type_periurban -0.029 0.016 -0.061 -0.029 0.002 -0.029 0
age_group40-59:type_urban -0.037 0.041 -0.118 -0.037 0.044 -0.037 0
age_group60-69:type_urban -0.080 0.033 -0.145 -0.080 -0.016 -0.080 0
age_group70-79:type_urban -0.096 0.023 -0.142 -0.096 -0.051 -0.096 0
age_group80+:type_urban -0.045 0.014 -0.072 -0.045 -0.018 -0.045 0
Random effects:
Name Model
id_space BYM2 model
Model hyperparameters:
mean sd 0.025quant 0.5quant 0.975quant mode
Precision for id_space 769.70 170.75 493.94 749.16 1163.02 707.78
Phi for id_space 1.00 0.00 1.00 1.00 1.00 1.00
Watanabe-Akaike information criterion (WAIC) ...: 46956.46
Effective number of parameters .................: 14.10
Marginal log-Likelihood: -22780.10
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mean 0.025quant 0.975quant
sexFemale:age_group40-59 1.0328554 0.9521324 1.1204224
sexMale:age_group40-59 1.4617288 1.3554925 1.5762916
sexFemale:age_group60-69 1.1041932 1.0346753 1.1783822
sexMale:age_group60-69 1.6187569 1.5253415 1.7178946
sexFemale:age_group70-79 1.3662585 1.3073578 1.4278140
sexMale:age_group70-79 1.7350302 1.6633802 1.8097682
sexFemale:age_group80+ 1.7048901 1.6631014 1.7477326
sexMale:age_group80+ 1.2082289 1.1778953 1.2393459
age_group40-59:type_periurban 1.0103543 0.9186166 1.1112535
age_group60-69:type_periurban 0.9636520 0.8930274 1.0398618
age_group70-79:type_periurban 0.9501108 0.9009913 1.0019082
age_group80+:type_periurban 0.9709716 0.9408893 1.0020165
age_group40-59:type_urban 0.9638461 0.8888322 1.0451923
age_group60-69:type_urban 0.9228728 0.8652073 0.9843828
age_group70-79:type_urban 0.9080343 0.8680080 0.9499086
age_group80+:type_urban 0.9560844 0.9308707 0.9819896
[1] -24.62719
Results are not conclusive, but rural municipalities appear to have a slightly higher excess mortality than municipalities classified as intermediate or urban.
Socio-economic position
The Swiss neighbourhood index of socio-economic position provides an estimate of socio-economic position (SEP) based on census data for 1.5 million buildings [@panczak2023swiss]. We consider the median index of each municipality, then group municipalities in quintiles before adding to the model (reference is 3rd quintile). Again, we consider the interaction with age.
model1.4b = INLA::inla(munici_observed ~ - 1 + offset(E) +
sex:age_group +
f(id_space, model = "bym2", graph = "data/nb/gg_wm_q.adj", scale.model = TRUE,
hyper = hyper.bym2, constr=TRUE) +
age_group:sep1 + age_group:sep2 + age_group:sep3 + age_group:sep4,
data = data1,
family = "Poisson",
control.compute = list(config = TRUE, waic = TRUE),
quantiles = c(0.025, 0.5, 0.975),
num.threads = threads,
safe = TRUE)
summary(model1.4b)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 12.2, Running = 6.83, Post = 0.776, Total = 19.8
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
sexFemale:age_group40-59 -0.026 0.035 -0.095 -0.026 0.042 -0.026 0
sexMale:age_group40-59 0.320 0.031 0.259 0.320 0.380 0.320 0
sexFemale:age_group60-69 0.004 0.028 -0.052 0.004 0.060 0.004 0
sexMale:age_group60-69 0.386 0.026 0.336 0.386 0.436 0.386 0
sexFemale:age_group70-79 0.213 0.019 0.176 0.213 0.249 0.213 0
sexMale:age_group70-79 0.452 0.017 0.418 0.452 0.487 0.452 0
sexFemale:age_group80+ 0.487 0.011 0.466 0.487 0.508 0.487 0
sexMale:age_group80+ 0.144 0.011 0.122 0.144 0.166 0.143 0
age_group40-59:sep1 0.146 0.056 0.036 0.146 0.256 0.146 0
age_group60-69:sep1 0.124 0.046 0.034 0.124 0.214 0.124 0
age_group70-79:sep1 0.103 0.031 0.042 0.103 0.165 0.103 0
age_group80+:sep1 0.047 0.019 0.009 0.047 0.085 0.047 0
age_group40-59:sep2 0.070 0.045 -0.018 0.070 0.159 0.070 0
age_group60-69:sep2 0.051 0.037 -0.022 0.051 0.124 0.051 0
age_group70-79:sep2 0.050 0.026 -0.001 0.050 0.101 0.050 0
age_group80+:sep2 0.023 0.016 -0.008 0.023 0.054 0.023 0
age_group40-59:sep3 0.044 0.045 -0.043 0.044 0.131 0.044 0
age_group60-69:sep3 0.058 0.036 -0.014 0.058 0.129 0.058 0
age_group70-79:sep3 0.039 0.025 -0.010 0.039 0.088 0.039 0
age_group80+:sep3 0.014 0.015 -0.015 0.014 0.043 0.014 0
age_group40-59:sep4 0.014 0.040 -0.065 0.014 0.092 0.014 0
age_group60-69:sep4 0.020 0.033 -0.044 0.020 0.084 0.020 0
age_group70-79:sep4 0.003 0.023 -0.041 0.003 0.048 0.003 0
age_group80+:sep4 -0.001 0.013 -0.028 -0.001 0.025 -0.001 0
Random effects:
Name Model
id_space BYM2 model
Model hyperparameters:
mean sd 0.025quant 0.5quant 0.975quant mode
Precision for id_space 953.636 242.033 576.637 920.044 1523.104 853.720
Phi for id_space 0.961 0.039 0.854 0.973 0.998 0.993
Watanabe-Akaike information criterion (WAIC) ...: 46981.46
Effective number of parameters .................: 15.61
Marginal log-Likelihood: -22832.06
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mean 0.025quant 0.975quant
sexFemale:age_group40-59 0.9741483 0.9095543 1.043342
sexMale:age_group40-59 1.3765909 1.2958055 1.462435
sexFemale:age_group60-69 1.0039996 0.9497057 1.061416
sexMale:age_group60-69 1.4710467 1.3990589 1.546774
sexFemale:age_group70-79 1.2368359 1.1920900 1.283311
sexMale:age_group70-79 1.5721162 1.5192425 1.626902
sexFemale:age_group80+ 1.6279431 1.5943636 1.662459
sexMale:age_group80+ 1.1543672 1.1292234 1.180209
age_group40-59:sep1 1.1572956 1.0368869 1.291668
age_group60-69:sep1 1.1319521 1.0343243 1.238768
age_group70-79:sep1 1.1089830 1.0429795 1.179106
age_group80+:sep1 1.0479697 1.0090922 1.088204
age_group40-59:sep2 1.0730148 0.9816756 1.172836
age_group60-69:sep2 1.0524842 0.9783167 1.132251
age_group70-79:sep2 1.0513682 0.9992543 1.106155
age_group80+:sep2 1.0229518 0.9917980 1.054962
age_group40-59:sep3 1.0449207 0.9574843 1.140330
age_group60-69:sep3 1.0591989 0.9864717 1.137270
age_group70-79:sep3 1.0397816 0.9903484 1.091648
age_group80+:sep3 1.0140302 0.9847559 1.044071
age_group40-59:sep4 1.0136215 0.9368113 1.096726
age_group60-69:sep4 1.0202303 0.9566172 1.088069
age_group70-79:sep4 1.0033216 0.9598346 1.048771
age_group80+:sep4 0.9985199 0.9725885 1.025117
[1] 0.3725698
A gradient appears clearly, but high uncertainty remains, so that we can conclude that municipalities of lowest median SEP (1st quintile) had a higher relative excess mortality in 2020 compared to municipalities of highest median SEP (5th quintile). As in other works, we observe that the gradient associated with SEP is less steep for older groups.
Borders
We now consider whether the municipality shares a border with another country.
model1.4c = INLA::inla(munici_observed ~ - 1 + offset(E) +
sex:age_group +
f(id_space, model = "bym2", graph = "data/nb/gg_wm_q.adj", scale.model = TRUE,
hyper = hyper.bym2, constr=TRUE) +
age_group:border,
data = data1,
family = "Poisson",
control.compute = list(config = TRUE, waic = TRUE),
quantiles = c(0.025, 0.5, 0.975),
num.threads = threads,
safe = TRUE)
summary(model1.4c)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 11.4, Running = 4.89, Post = 0.614, Total = 16.9
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
sexFemale:age_group40-59 0.004 0.025 -0.046 0.004 0.054 0.004 0
sexMale:age_group40-59 0.352 0.020 0.313 0.352 0.391 0.352 0
sexFemale:age_group60-69 0.027 0.021 -0.013 0.027 0.068 0.027 0
sexMale:age_group60-69 0.411 0.016 0.379 0.411 0.443 0.411 0
sexFemale:age_group70-79 0.238 0.014 0.211 0.238 0.265 0.238 0
sexMale:age_group70-79 0.477 0.012 0.454 0.477 0.500 0.477 0
sexFemale:age_group80+ 0.495 0.007 0.481 0.495 0.509 0.495 0
sexMale:age_group80+ 0.151 0.008 0.136 0.151 0.167 0.151 0
age_group40-59:border 0.057 0.039 -0.019 0.057 0.134 0.057 0
age_group60-69:border 0.089 0.032 0.026 0.089 0.152 0.089 0
age_group70-79:border 0.030 0.023 -0.016 0.030 0.076 0.030 0
age_group80+:border 0.036 0.016 0.004 0.036 0.068 0.036 0
Random effects:
Name Model
id_space BYM2 model
Model hyperparameters:
mean sd 0.025quant 0.5quant 0.975quant mode
Precision for id_space 731.477 160.745 471.784 712.153 1101.699 673.047
Phi for id_space 0.965 0.034 0.872 0.976 0.998 0.994
Watanabe-Akaike information criterion (WAIC) ...: 46978.24
Effective number of parameters .................: 15.70
Marginal log-Likelihood: -22757.89
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mean 0.025quant 0.975quant
sexFemale:age_group40-59 1.004492 0.9555093 1.055988
sexMale:age_group40-59 1.422137 1.3678876 1.478544
sexFemale:age_group60-69 1.027617 0.9867954 1.070132
sexMale:age_group60-69 1.508287 1.4609101 1.557209
sexFemale:age_group70-79 1.268789 1.2353376 1.303158
sexMale:age_group70-79 1.611258 1.5747842 1.648597
sexFemale:age_group80+ 1.640737 1.6180686 1.663784
sexMale:age_group80+ 1.163525 1.1455869 1.181776
age_group40-59:border 1.058737 0.9808065 1.142876
age_group60-69:border 1.092784 1.0259978 1.163944
age_group70-79:border 1.030359 0.9842597 1.078644
age_group80+:border 1.036409 1.0037615 1.070200
[1] -2.845527
We observe a tendency towards higher relative excess mortality in municipalities sharing a border with another country. However, this indicator is not entirely satisfying, as the level of connection with other countries is more of interest than just sharing a border.
Language
Most Swiss municipalities have one official language: German, French or Italian. A few municipalities have several official languages, but given the relatively low numbers, we consider only the majority language. The difficulty is the colinearity between language regions and the first COVID-19 wave of 2020, that primarily affected Ticino (Italian) and Southwestern Switzerland (French), mostly because of how the initial global spread of COVID-19 occurred (with large early epidemics in Italy and then France). These effects are much larger than any effect that could be attributed to cultural differences between language regions, so it is quite difficult to estimate the latter. We still attempt to do so by adding the language of each municipality (reference is German) to our model.
model1.4d = INLA::inla(munici_observed ~ - 1 + offset(E) +
sex:age_group +
f(id_space, model = "bym2", graph = "data/nb/gg_wm_q.adj", scale.model = TRUE,
hyper = hyper.bym2, constr=TRUE) +
age_group:lang_fr + age_group:lang_it,
data = data1,
family = "Poisson",
control.compute = list(config = TRUE, waic = TRUE),
quantiles = c(0.025, 0.5, 0.975),
num.threads = threads,
safe = TRUE)
summary(model1.4d)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 12.9, Running = 6.13, Post = 0.684, Total = 19.7
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
sexFemale:age_group40-59 -0.016 0.026 -0.067 -0.016 0.035 -0.016 0
sexMale:age_group40-59 0.332 0.021 0.290 0.332 0.373 0.332 0
sexFemale:age_group60-69 0.008 0.021 -0.034 0.008 0.050 0.008 0
sexMale:age_group60-69 0.393 0.017 0.359 0.393 0.426 0.393 0
sexFemale:age_group70-79 0.195 0.014 0.167 0.195 0.223 0.195 0
sexMale:age_group70-79 0.435 0.012 0.411 0.435 0.460 0.435 0
sexFemale:age_group80+ 0.467 0.008 0.452 0.467 0.482 0.467 0
sexMale:age_group80+ 0.123 0.008 0.107 0.123 0.140 0.123 0
age_group40-59:lang_fr 0.058 0.036 -0.012 0.058 0.128 0.058 0
age_group60-69:lang_fr 0.071 0.030 0.011 0.071 0.130 0.071 0
age_group70-79:lang_fr 0.131 0.021 0.089 0.132 0.173 0.132 0
age_group80+:lang_fr 0.082 0.015 0.052 0.082 0.111 0.083 0
age_group40-59:lang_it 0.210 0.070 0.072 0.210 0.348 0.210 0
age_group60-69:lang_it 0.223 0.056 0.113 0.223 0.334 0.223 0
age_group70-79:lang_it 0.158 0.039 0.082 0.159 0.235 0.159 0
age_group80+:lang_it 0.138 0.025 0.089 0.138 0.187 0.139 0
Random effects:
Name Model
id_space BYM2 model
Model hyperparameters:
mean sd 0.025quant 0.5quant 0.975quant mode
Precision for id_space 3094.267 1854.33 1064.046 2610.345 7994.539 1934.579
Phi for id_space 0.856 0.14 0.464 0.903 0.992 0.981
Watanabe-Akaike information criterion (WAIC) ...: 46965.64
Effective number of parameters .................: 10.73
Marginal log-Likelihood: -22754.64
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mean 0.025quant 0.975quant
sexFemale:age_group40-59 0.984102 0.9348487 1.035972
sexMale:age_group40-59 1.393248 1.3370822 1.451822
sexFemale:age_group60-69 1.008262 0.9668414 1.051491
sexMale:age_group60-69 1.480813 1.4323366 1.531006
sexFemale:age_group70-79 1.215801 1.1822351 1.250423
sexMale:age_group70-79 1.545595 1.5087304 1.583527
sexFemale:age_group80+ 1.594749 1.5711025 1.619273
sexMale:age_group80+ 1.131428 1.1129551 1.150489
age_group40-59:lang_fr 1.059685 0.9877626 1.136654
age_group60-69:lang_fr 1.073166 1.0115231 1.138320
age_group70-79:lang_fr 1.140493 1.0931359 1.189363
age_group80+:lang_fr 1.085616 1.0538201 1.117248
age_group40-59:lang_it 1.233394 1.0743391 1.415845
age_group60-69:lang_it 1.250118 1.1192395 1.396116
age_group70-79:lang_it 1.171723 1.0853890 1.264497
age_group80+:lang_it 1.148203 1.0929745 1.205127
[1] -15.44103
At first sight, we may thing that there is a large effect of language region on excess mortality, with around 5-15% more deaths than expected in French-speaking municipalities and 15-30% more in Italian-speaking municipalities compared to German. However, as expected this association is likely confounded by the regional variability associated with COVID-19 waves in 2020. Indeed, if we now look at the geographically-structured municipality effect for this model, which can be interpreted as residual effects, we see that the higher excess in South and Southwestern Switzerland is now more evenly distributed (captured by the language effect), while French-speaking regions that were comparatively less impacted during the first wave (such as Neuchâtel and Jura) now have a negative municipality effect to compensate. These nonsensical results highlight the difficulty to estimate the effect of language regions. For this reason, in the following we rely upon observing the residual municipality effects to draw conclusion about the association with language rather than using the language as a fixed effect, as shown in the next map based on model 1.3.
We can make two observations on this last map. First, French-speaking and Italian-speaking municipalities were not systematically more affected than German-speaking, with notable exceptions in the French-speaking area around Neuchâtel and in Italian-speaking municipalities of canton Graubunden. Second, there is a clear separation between the French-speaking and German-speaking municipalities around canton Fribourg, suggesting lower levels of connectivity between these communities.
Referendums on COVID-19 measures
We now focus on results from two referendums about COVID-19 control measures held in June and November 2020. The point here is not to look at causality one way or the other, as we look at overall excess for 2020, and the voting took place at two separated points. A preliminary analysis has reported a negative association between the proportion of “yes” vote at the November referendum at the cantonal level and 7-day incidence on December 7, 2021 (https://smw.ch/index.php/smw/announcement/view/50). We classify municipalities according to the proportion of “yes” vote (expressing support of government-issued measures aimed at controlling COVID-19) at each vote, in quintiles (taking the 5th quintile - highest support - as a reference).
model1.4e = INLA::inla(munici_observed ~ - 1 + offset(E) +
sex:age_group +
f(id_space, model = "bym2", graph = "data/nb/gg_wm_q.adj", scale.model = TRUE,
hyper = hyper.bym2, constr=TRUE) +
age_group:vote_jun_q1 + age_group:vote_jun_q2 + age_group:vote_jun_q3 + age_group:vote_jun_q4,
data = data1,
family = "Poisson",
control.compute = list(config = TRUE, waic = TRUE),
quantiles = c(0.025, 0.5, 0.975),
num.threads = threads,
safe = TRUE)
summary(model1.4e)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 12.9, Running = 8.18, Post = 0.71, Total = 21.8
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
sexFemale:age_group40-59 -0.006 0.031 -0.066 -0.006 0.054 -0.006 0
sexMale:age_group40-59 0.341 0.026 0.290 0.341 0.392 0.341 0
sexFemale:age_group60-69 0.026 0.025 -0.023 0.026 0.075 0.026 0
sexMale:age_group60-69 0.409 0.022 0.366 0.409 0.452 0.409 0
sexFemale:age_group70-79 0.229 0.017 0.196 0.229 0.261 0.229 0
sexMale:age_group70-79 0.467 0.015 0.437 0.467 0.497 0.467 0
sexFemale:age_group80+ 0.488 0.009 0.470 0.488 0.506 0.488 0
sexMale:age_group80+ 0.144 0.010 0.125 0.144 0.164 0.144 0
age_group40-59:vote_jun_q1 0.026 0.053 -0.078 0.026 0.129 0.026 0
age_group60-69:vote_jun_q1 0.020 0.043 -0.064 0.020 0.104 0.020 0
age_group70-79:vote_jun_q1 0.046 0.030 -0.013 0.046 0.105 0.046 0
age_group80+:vote_jun_q1 0.051 0.018 0.014 0.051 0.087 0.051 0
age_group40-59:vote_jun_q2 0.027 0.048 -0.068 0.027 0.122 0.027 0
age_group60-69:vote_jun_q2 0.046 0.039 -0.031 0.046 0.124 0.046 0
age_group70-79:vote_jun_q2 0.039 0.028 -0.015 0.039 0.094 0.039 0
age_group80+:vote_jun_q2 0.029 0.017 -0.004 0.029 0.063 0.029 0
age_group40-59:vote_jun_q3 0.048 0.043 -0.037 0.048 0.133 0.048 0
age_group60-69:vote_jun_q3 0.044 0.035 -0.025 0.044 0.113 0.044 0
age_group70-79:vote_jun_q3 0.021 0.025 -0.028 0.021 0.069 0.021 0
age_group80+:vote_jun_q3 0.015 0.015 -0.015 0.015 0.044 0.015 0
age_group40-59:vote_jun_q4 0.029 0.039 -0.048 0.029 0.106 0.029 0
age_group60-69:vote_jun_q4 0.009 0.032 -0.054 0.009 0.072 0.009 0
age_group70-79:vote_jun_q4 0.007 0.022 -0.036 0.007 0.050 0.007 0
age_group80+:vote_jun_q4 0.010 0.013 -0.016 0.010 0.036 0.010 0
Random effects:
Name Model
id_space BYM2 model
Model hyperparameters:
mean sd 0.025quant 0.5quant 0.975quant mode
Precision for id_space 721.593 155.224 469.453 703.38 1077.885 666.466
Phi for id_space 0.971 0.029 0.892 0.98 0.998 0.995
Watanabe-Akaike information criterion (WAIC) ...: 46986.99
Effective number of parameters .................: 16.45
Marginal log-Likelihood: -22840.74
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mean 0.025quant 0.975quant
sexFemale:age_group40-59 0.9937242 0.9357287 1.055319
sexMale:age_group40-59 1.4062295 1.3365162 1.479588
sexFemale:age_group60-69 1.0263718 0.9770590 1.078180
sexMale:age_group60-69 1.5050851 1.4421673 1.570764
sexFemale:age_group70-79 1.2568619 1.2166749 1.298395
sexMale:age_group70-79 1.5955900 1.5484738 1.644169
sexFemale:age_group80+ 1.6295494 1.6007447 1.658962
sexMale:age_group80+ 1.1550764 1.1329114 1.177724
age_group40-59:vote_jun_q1 1.0258405 0.9251239 1.137524
age_group60-69:vote_jun_q1 1.0205412 0.9383788 1.109900
age_group70-79:vote_jun_q1 1.0467656 0.9867862 1.110398
age_group80+:vote_jun_q1 1.0518788 1.0144928 1.090666
age_group40-59:vote_jun_q2 1.0272162 0.9343679 1.129292
age_group60-69:vote_jun_q2 1.0474009 0.9694678 1.131602
age_group70-79:vote_jun_q2 1.0399246 0.9846724 1.098283
age_group80+:vote_jun_q2 1.0296348 0.9958456 1.064583
age_group40-59:vote_jun_q3 1.0491657 0.9634619 1.142494
age_group60-69:vote_jun_q3 1.0450681 0.9754763 1.119623
age_group70-79:vote_jun_q3 1.0211802 0.9728508 1.071911
age_group80+:vote_jun_q3 1.0147417 0.9852143 1.045151
age_group40-59:vote_jun_q4 1.0295687 0.9530988 1.112173
age_group60-69:vote_jun_q4 1.0091703 0.9475082 1.074846
age_group70-79:vote_jun_q4 1.0069670 0.9643623 1.051454
age_group80+:vote_jun_q4 1.0103917 0.9844441 1.037026
[1] 5.90882
model1.4f = INLA::inla(munici_observed ~ - 1 + offset(E) +
sex:age_group +
f(id_space, model = "bym2", graph = "data/nb/gg_wm_q.adj", scale.model = TRUE,
hyper = hyper.bym2, constr=TRUE) +
age_group:vote_nov_q1 + age_group:vote_nov_q2 + age_group:vote_nov_q3 + age_group:vote_nov_q4,
data = data1,
family = "Poisson",
control.compute = list(config = TRUE, waic = TRUE),
quantiles = c(0.025, 0.5, 0.975),
num.threads = threads,
safe = TRUE)
summary(model1.4f)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 11.5, Running = 7.01, Post = 0.678, Total = 19.2
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
sexFemale:age_group40-59 0.004 0.031 -0.058 0.004 0.066 0.004 0
sexMale:age_group40-59 0.350 0.027 0.298 0.350 0.403 0.350 0
sexFemale:age_group60-69 0.025 0.025 -0.024 0.025 0.075 0.025 0
sexMale:age_group60-69 0.409 0.022 0.366 0.409 0.452 0.409 0
sexFemale:age_group70-79 0.220 0.017 0.187 0.220 0.253 0.220 0
sexMale:age_group70-79 0.459 0.015 0.428 0.458 0.489 0.458 0
sexFemale:age_group80+ 0.484 0.009 0.467 0.484 0.502 0.484 0
sexMale:age_group80+ 0.140 0.010 0.121 0.140 0.160 0.140 0
age_group40-59:vote_nov_q1 0.015 0.054 -0.091 0.015 0.121 0.015 0
age_group60-69:vote_nov_q1 0.028 0.044 -0.059 0.028 0.114 0.028 0
age_group70-79:vote_nov_q1 0.055 0.031 -0.006 0.055 0.115 0.055 0
age_group80+:vote_nov_q1 0.047 0.018 0.011 0.047 0.083 0.047 0
age_group40-59:vote_nov_q2 0.039 0.049 -0.056 0.039 0.135 0.039 0
age_group60-69:vote_nov_q2 0.041 0.039 -0.034 0.041 0.117 0.041 0
age_group70-79:vote_nov_q2 0.070 0.027 0.017 0.070 0.123 0.070 0
age_group80+:vote_nov_q2 0.035 0.016 0.003 0.035 0.067 0.035 0
age_group40-59:vote_nov_q3 0.023 0.041 -0.058 0.023 0.104 0.023 0
age_group60-69:vote_nov_q3 0.022 0.034 -0.045 0.022 0.090 0.022 0
age_group70-79:vote_nov_q3 0.026 0.024 -0.020 0.026 0.073 0.026 0
age_group80+:vote_nov_q3 0.021 0.014 -0.007 0.021 0.049 0.021 0
age_group40-59:vote_nov_q4 -0.004 0.039 -0.081 -0.004 0.073 -0.004 0
age_group60-69:vote_nov_q4 0.022 0.032 -0.041 0.022 0.085 0.022 0
age_group70-79:vote_nov_q4 0.016 0.022 -0.028 0.016 0.059 0.016 0
age_group80+:vote_nov_q4 0.018 0.013 -0.008 0.018 0.044 0.018 0
Random effects:
Name Model
id_space BYM2 model
Model hyperparameters:
mean sd 0.025quant 0.5quant 0.975quant mode
Precision for id_space 778.676 175.159 497.510 757.022 1183.681 713.291
Phi for id_space 0.968 0.031 0.883 0.978 0.998 0.995
Watanabe-Akaike information criterion (WAIC) ...: 46987.14
Effective number of parameters .................: 16.24
Marginal log-Likelihood: -22839.05
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mean 0.025quant 0.975quant
sexFemale:age_group40-59 1.0039221 0.9438878 1.067782
sexMale:age_group40-59 1.4197156 1.3466467 1.496762
sexFemale:age_group60-69 1.0258157 0.9760307 1.078150
sexMale:age_group60-69 1.5047528 1.4413042 1.571014
sexFemale:age_group70-79 1.2464855 1.2060601 1.288292
sexMale:age_group70-79 1.5817034 1.5345926 1.630300
sexFemale:age_group80+ 1.6233372 1.5949562 1.652343
sexMale:age_group80+ 1.1506858 1.1288439 1.173017
age_group40-59:vote_nov_q1 1.0153837 0.9131079 1.129113
age_group60-69:vote_nov_q1 1.0279403 0.9426185 1.120980
age_group70-79:vote_nov_q1 1.0562528 0.9942472 1.122120
age_group80+:vote_nov_q1 1.0477921 1.0107599 1.086171
age_group40-59:vote_nov_q2 1.0398886 0.9450819 1.144202
age_group60-69:vote_nov_q2 1.0422102 0.9661591 1.124242
age_group70-79:vote_nov_q2 1.0725935 1.0172738 1.130910
age_group80+:vote_nov_q2 1.0354984 1.0028146 1.069223
age_group40-59:vote_nov_q3 1.0232793 0.9434513 1.109856
age_group60-69:vote_nov_q3 1.0226900 0.9559212 1.094115
age_group70-79:vote_nov_q3 1.0267479 0.9800980 1.075602
age_group80+:vote_nov_q3 1.0212436 0.9932757 1.049953
age_group40-59:vote_nov_q4 0.9957504 0.9217397 1.075701
age_group60-69:vote_nov_q4 1.0221936 0.9598390 1.088595
age_group70-79:vote_nov_q4 1.0160863 0.9728309 1.061257
age_group80+:vote_nov_q4 1.0183049 0.9923169 1.044957
[1] 6.059512
In both cases, high uncertainty remains, although it appears that excess mortality in age group 80+ appears to be consistently about 5% higher in municipalities expressing lowest support to control measures (first quantile) in both referendums.
Multivariable model
We now jointly estimate the effects of interest identified in the univariable analysis: rural or urban status, border, median SEP quintile and results from the COVID-19 referendums (using only the June referendum to limit complexity).
model1.5 = INLA::inla(munici_observed ~ - 1 + offset(E) +
sex:age_group +
f(id_space, model = "bym2", graph = "data/nb/gg_wm_q.adj", scale.model = TRUE,
hyper = hyper.bym2, constr=TRUE) +
age_group:border +
age_group:type_periurban + age_group:type_urban +
age_group:sep1 + age_group:sep2 + age_group:sep3 + age_group:sep4 +
age_group:vote_jun_q1 + age_group:vote_jun_q2 + age_group:vote_jun_q3 + age_group:vote_jun_q4,
data = data1,
family = "Poisson",
control.compute = list(config = TRUE, waic = TRUE),
quantiles = c(0.025, 0.5, 0.975),
num.threads = threads,
safe = TRUE)
summary(model1.5)
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 12.7, Running = 11.3, Post = 0.778, Total = 24.8
Fixed effects:
mean sd 0.025quant 0.5quant 0.975quant mode kld
sexFemale:age_group40-59 -0.034 0.062 -0.155 -0.034 0.087 -0.034 0
sexMale:age_group40-59 0.314 0.059 0.197 0.314 0.431 0.314 0
sexFemale:age_group60-69 0.045 0.049 -0.052 0.045 0.142 0.045 0
sexMale:age_group60-69 0.427 0.048 0.334 0.427 0.521 0.427 0
sexFemale:age_group70-79 0.293 0.034 0.227 0.293 0.360 0.293 0
sexMale:age_group70-79 0.533 0.033 0.468 0.533 0.599 0.533 0
sexFemale:age_group80+ 0.509 0.020 0.470 0.509 0.548 0.509 0
sexMale:age_group80+ 0.164 0.020 0.125 0.164 0.204 0.164 0
age_group40-59:border 0.061 0.040 -0.017 0.061 0.140 0.061 0
age_group60-69:border 0.095 0.033 0.031 0.095 0.160 0.095 0
age_group70-79:border 0.033 0.023 -0.013 0.033 0.079 0.033 0
age_group80+:border 0.038 0.016 0.007 0.038 0.069 0.038 0
age_group40-59:type_periurban 0.025 0.051 -0.075 0.025 0.124 0.025 0
age_group60-69:type_periurban -0.028 0.041 -0.107 -0.028 0.052 -0.028 0
age_group70-79:type_periurban -0.043 0.028 -0.098 -0.043 0.013 -0.043 0
age_group80+:type_periurban -0.021 0.017 -0.054 -0.021 0.012 -0.021 0
age_group40-59:type_urban -0.017 0.049 -0.113 -0.017 0.079 -0.017 0
age_group60-69:type_urban -0.070 0.039 -0.146 -0.070 0.006 -0.070 0
age_group70-79:type_urban -0.092 0.027 -0.145 -0.092 -0.038 -0.092 0
age_group80+:type_urban -0.033 0.016 -0.065 -0.033 -0.001 -0.033 0
age_group40-59:sep1 0.154 0.060 0.036 0.154 0.271 0.154 0
age_group60-69:sep1 0.104 0.049 0.007 0.104 0.201 0.104 0
age_group70-79:sep1 0.081 0.034 0.014 0.081 0.147 0.081 0
age_group80+:sep1 0.031 0.021 -0.011 0.031 0.072 0.031 0
age_group40-59:sep2 0.078 0.048 -0.017 0.078 0.172 0.078 0
age_group60-69:sep2 0.047 0.040 -0.032 0.047 0.125 0.047 0
age_group70-79:sep2 0.042 0.028 -0.013 0.042 0.097 0.042 0
age_group80+:sep2 0.012 0.017 -0.022 0.012 0.046 0.012 0
age_group40-59:sep3 0.050 0.047 -0.041 0.050 0.142 0.050 0
age_group60-69:sep3 0.050 0.038 -0.024 0.050 0.125 0.050 0
age_group70-79:sep3 0.034 0.026 -0.017 0.034 0.085 0.034 0
age_group80+:sep3 0.007 0.016 -0.024 0.007 0.038 0.007 0
age_group40-59:sep4 0.013 0.041 -0.067 0.013 0.092 0.013 0
age_group60-69:sep4 0.012 0.033 -0.053 0.012 0.077 0.012 0
age_group70-79:sep4 0.002 0.023 -0.042 0.002 0.047 0.002 0
age_group80+:sep4 -0.003 0.014 -0.030 -0.003 0.023 -0.003 0
age_group40-59:vote_jun_q1 -0.044 0.063 -0.167 -0.044 0.079 -0.044 0
age_group60-69:vote_jun_q1 -0.046 0.050 -0.145 -0.046 0.052 -0.046 0
age_group70-79:vote_jun_q1 -0.046 0.036 -0.116 -0.046 0.024 -0.046 0
age_group80+:vote_jun_q1 0.015 0.022 -0.028 0.015 0.059 0.015 0
age_group40-59:vote_jun_q2 -0.027 0.056 -0.136 -0.027 0.082 -0.027 0
age_group60-69:vote_jun_q2 -0.005 0.045 -0.092 -0.005 0.082 -0.005 0
age_group70-79:vote_jun_q2 -0.031 0.032 -0.093 -0.031 0.032 -0.031 0
age_group80+:vote_jun_q2 0.002 0.020 -0.036 0.002 0.041 0.002 0
age_group40-59:vote_jun_q3 0.013 0.047 -0.079 0.013 0.105 0.013 0
age_group60-69:vote_jun_q3 0.012 0.038 -0.062 0.012 0.087 0.012 0
age_group70-79:vote_jun_q3 -0.026 0.027 -0.079 -0.026 0.027 -0.026 0
age_group80+:vote_jun_q3 -0.002 0.016 -0.034 -0.002 0.030 -0.002 0
age_group40-59:vote_jun_q4 0.005 0.041 -0.075 0.005 0.085 0.005 0
age_group60-69:vote_jun_q4 -0.009 0.033 -0.074 -0.009 0.056 -0.009 0
age_group70-79:vote_jun_q4 -0.019 0.023 -0.064 -0.019 0.025 -0.019 0
age_group80+:vote_jun_q4 0.000 0.014 -0.027 -0.001 0.026 -0.001 0
Random effects:
Name Model
id_space BYM2 model
Model hyperparameters:
mean sd 0.025quant 0.5quant 0.975quant mode
Precision for id_space 991.13 254.25 596.41 955.428 1590.448 885.058
Phi for id_space 0.96 0.04 0.85 0.972 0.997 0.993
Watanabe-Akaike information criterion (WAIC) ...: 46977.19
Effective number of parameters .................: 20.84
Marginal log-Likelihood: -23009.82
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
mean 0.025quant 0.975quant
sexFemale:age_group40-59 0.9666013 0.8563893 1.0910005
sexMale:age_group40-59 1.3686679 1.2179587 1.5380310
sexFemale:age_group60-69 1.0462751 0.9496527 1.1527377
sexMale:age_group60-69 1.5333525 1.3963914 1.6837635
sexFemale:age_group70-79 1.3408146 1.2548726 1.4326675
sexMale:age_group70-79 1.7045674 1.5967374 1.8197116
sexFemale:age_group80+ 1.6633919 1.5998703 1.7295302
sexMale:age_group80+ 1.1786524 1.1331526 1.2260419
age_group40-59:border 1.0631651 0.9828825 1.1500140
age_group60-69:border 1.0998905 1.0314003 1.1729393
age_group70-79:border 1.0332679 0.9868916 1.0818240
age_group80+:border 1.0386755 1.0069128 1.0714783
age_group40-59:type_periurban 1.0248268 0.9276523 1.1321802
age_group60-69:type_periurban 0.9725576 0.8982777 1.0529789
age_group70-79:type_periurban 0.9579667 0.9062531 1.0126292
age_group80+:type_periurban 0.9790618 0.9473143 1.0118681
age_group40-59:type_urban 0.9835295 0.8934561 1.0826843
age_group60-69:type_urban 0.9323081 0.8640422 1.0059673
age_group70-79:type_urban 0.9125356 0.8651183 0.9625515
age_group80+:type_urban 0.9673163 0.9369605 0.9986545
age_group40-59:sep1 1.1660524 1.0364677 1.3118175
age_group60-69:sep1 1.1095320 1.0069482 1.2225377
age_group70-79:sep1 1.0840339 1.0144658 1.1583046
age_group80+:sep1 1.0309768 0.9888867 1.0746957
age_group40-59:sep2 1.0805877 0.9828967 1.1879689
age_group60-69:sep2 1.0476386 0.9688241 1.1328388
age_group70-79:sep2 1.0426784 0.9869340 1.1015156
age_group80+:sep2 1.0121066 0.9783764 1.0468485
age_group40-59:sep3 1.0517508 0.9594131 1.1529621
age_group60-69:sep3 1.0516742 0.9760950 1.1330867
age_group70-79:sep3 1.0346079 0.9828297 1.0890730
age_group80+:sep3 1.0067361 0.9758132 1.0385193
age_group40-59:sep4 1.0127963 0.9352640 1.0967528
age_group60-69:sep4 1.0124771 0.9488109 1.0804111
age_group70-79:sep4 1.0023298 0.9585406 1.0481120
age_group80+:sep4 0.9968242 0.9707407 1.0235840
age_group40-59:vote_jun_q1 0.9570260 0.8463074 1.0822419
age_group60-69:vote_jun_q1 0.9546522 0.8653242 1.0532156
age_group70-79:vote_jun_q1 0.9551814 0.8907763 1.0242775
age_group80+:vote_jun_q1 1.0155007 0.9725241 1.0604820
age_group40-59:vote_jun_q2 0.9733684 0.8727783 1.0855601
age_group60-69:vote_jun_q2 0.9948550 0.9116738 1.0856367
age_group70-79:vote_jun_q2 0.9698372 0.9114032 1.0320413
age_group80+:vote_jun_q2 1.0024431 0.9646702 1.0417631
age_group40-59:vote_jun_q3 1.0129856 0.9237338 1.1108673
age_group60-69:vote_jun_q3 1.0125268 0.9394837 1.0912554
age_group70-79:vote_jun_q3 0.9743810 0.9242425 1.0272558
age_group80+:vote_jun_q3 0.9980411 0.9663186 1.0308565
age_group40-59:vote_jun_q4 1.0050448 0.9281370 1.0883292
age_group60-69:vote_jun_q4 0.9910492 0.9290419 1.0572002
age_group70-79:vote_jun_q4 0.9810476 0.9383909 1.0256546
age_group80+:vote_jun_q4 0.9995027 0.9732801 1.0264680
[1] -3.897117
From this multivariate analysis, it appears that the only consistent association is with the median SEP of the municipality, and is especially marked age groups 40 to 79. There is also some indication that border municipalities and urban areas were associated with comparatively higher excess mortality in 2020, but the uncertainty remains high. Estimates of an association with voting results are faint. There are also some interesting patterns in the residual effects at the level of the municipality (adjusting for all aforementioned covariates), with in particular, expected higher excesses in Ticino and Southwestern Switzerland, a visible language barrier between French-speaking and German-speaking regions, lower excess in the large cities of the German-speaking part (Zurich, Basel, Bern) and in relatively isolated valleys of Graubunden.
Step 2: multivariate model with full uncertainty propagation
In the previous section we modeled the variation of the median excess mortality over 2020 by municipality. This approach underestimates the uncertainty from two sources, first from the prediction error in the expected mortality at the cantonal level, second from the downscaling to the municipal level. At this stage, we bring back these two sources of uncertainty in the final estimates by repeatedly fitting model 1.5 to 50 different sets of posterior draws of excess mortality by municipality, then combining with equal weights.
Call:
c("inla.core(formula = formula, family = family, contrasts = contrasts, ", " data = data,
quantiles = quantiles, E = E, offset = offset, ", " scale = scale, weights = weights,
Ntrials = Ntrials, strata = strata, ", " lp.scale = lp.scale, link.covariates =
link.covariates, verbose = verbose, ", " lincomb = lincomb, selection = selection,
control.compute = control.compute, ", " control.predictor = control.predictor,
control.family = control.family, ", " control.inla = control.inla, control.fixed =
control.fixed, ", " control.mode = control.mode, control.expert = control.expert, ", "
control.hazard = control.hazard, control.lincomb = control.lincomb, ", " control.update =
control.update, control.lp.scale = control.lp.scale, ", " control.pardiso =
control.pardiso, only.hyperparam = only.hyperparam, ", " inla.call = inla.call, inla.arg
= inla.arg, num.threads = num.threads, ", " blas.num.threads = blas.num.threads, keep =
keep, working.directory = working.directory, ", " silent = silent, inla.mode = inla.mode,
safe = FALSE, debug = debug, ", " .parent.frame = .parent.frame)")
Time used:
Pre = 478, Running = 291, Post = 28.1, Total = 797
Fixed effects:
mean sd
sexFemale:age_group40-59 -0.051 0.091
sexMale:age_group40-59 0.265 0.080
sexFemale:age_group60-69 -0.022 0.075
sexMale:age_group60-69 0.299 0.075
sexFemale:age_group70-79 0.208 0.062
sexMale:age_group70-79 0.403 0.055
sexFemale:age_group80+ 0.471 0.040
sexMale:age_group80+ 0.132 0.046
age_group40-59:border 0.030 0.072
age_group60-69:border 0.065 0.056
age_group70-79:border 0.029 0.046
age_group80+:border 0.034 0.035
age_group40-59:type_rural 0.011 0.078
age_group60-69:type_rural 0.007 0.065
age_group70-79:type_rural 0.006 0.042
age_group80+:type_rural 0.001 0.027
age_group40-59:type_urban 0.015 0.060
age_group60-69:type_urban 0.004 0.055
age_group70-79:type_urban -0.005 0.038
age_group80+:type_urban 0.004 0.023
age_group40-59:sep1 0.070 0.097
age_group60-69:sep1 0.058 0.086
age_group70-79:sep1 0.051 0.060
age_group80+:sep1 0.015 0.040
age_group40-59:sep2 0.055 0.078
age_group60-69:sep2 0.051 0.073
age_group70-79:sep2 0.045 0.051
age_group80+:sep2 0.009 0.036
age_group40-59:sep3 0.027 0.075
age_group60-69:sep3 0.045 0.064
age_group70-79:sep3 0.031 0.045
age_group80+:sep3 0.009 0.032
age_group40-59:sep4 0.016 0.065
age_group60-69:sep4 0.037 0.049
age_group70-79:sep4 0.008 0.039
age_group80+:sep4 -0.005 0.026
age_group40-59:vote_jun_q1 -0.053 0.098
age_group60-69:vote_jun_q1 -0.028 0.076
age_group70-79:vote_jun_q1 -0.039 0.064
age_group80+:vote_jun_q1 -0.003 0.044
age_group40-59:vote_jun_q2 -0.028 0.087
age_group60-69:vote_jun_q2 -0.006 0.068
age_group70-79:vote_jun_q2 -0.033 0.061
age_group80+:vote_jun_q2 -0.007 0.036
age_group40-59:vote_jun_q3 -0.022 0.076
age_group60-69:vote_jun_q3 -0.001 0.060
age_group70-79:vote_jun_q3 -0.026 0.052
age_group80+:vote_jun_q3 -0.006 0.028
age_group40-59:vote_jun_q4 -0.017 0.069
age_group60-69:vote_jun_q4 -0.020 0.049
age_group70-79:vote_jun_q4 -0.019 0.037
age_group80+:vote_jun_q4 -0.003 0.025
Random effects:
Name Model
id_space BYM2 model
Model hyperparameters:
mean sd
Precision for id_space 85.743 20.277
Phi for id_space 0.418 0.174
Marginal log-Likelihood: -43933.84
is computed
Posterior summaries for the linear predictor and the fitted values are computed
(Posterior marginals needs also 'control.compute=list(return.marginals.predictor=TRUE)')
As expected, this approach leads to a dilution of the observed associations between relative excess mortality and local covariates. We still observe a linear gradient in the association between excess mortality and median SEP at the municipal level in age groups 40 to 79, and a likely association between excess mortality and border municipalities, although in both cases with higher uncertainty. We also observe similar patterns in the residual effects at the level of the municipality, again with higher uncertainty.